﻿#include "topo_edge.h"
#include "topo_coedge.h"
#include "topo_vertex.h"

CAGD::TopoEdge::TopoEdge() : m_start(nullptr), m_end(nullptr), m_coedge(nullptr), m_dir(TopoDir::FORWARD)
{
}

CAGD::TopoEdge::TopoEdge(Handle(GeomCurve) curve) : TopoEdge()
{
    double s = curve->FirstParameter();
    double e = curve->LastParameter();

    m_curve = curve;
    m_start = new TopoVertex(curve->Value(s));
    m_end = new TopoVertex(curve->Value(s));

    // 创建 coedge
    TopoCoedge *co1 = new TopoCoedge;
    TopoCoedge *co2 = new TopoCoedge;

    // 建立拓扑连接
    m_coedge = co1;
    co1->Edge() = this;
    co2->Edge() = this;
    co1->Twin() = co2;
    co2->Twin() = co1;

    // 设置顶点的 edge
    m_start->Edges().insert(this);
    m_end->Edges().insert(this);
}

CAGD::TopoEdge::TopoEdge(TopoVertex *start, TopoVertex *end) : TopoEdge()
{
    m_start = start;
    m_end = end;

    // 创建 coedge
    TopoCoedge *co1 = new TopoCoedge;
    TopoCoedge *co2 = new TopoCoedge;

    // 建立拓扑连接
    m_coedge = co1;
    co1->Edge() = this;
    co2->Edge() = this;
    co1->Twin() = co2;
    co2->Twin() = co1;

    // 设置顶点的 edge
    start->Edges().insert(this);
    end->Edges().insert(this);
}

CAGD::TopoEdge::~TopoEdge()
{
    // 解除连接，删除 coedge（coedge 会删除 twin）
    if (m_coedge != nullptr)
    {
        m_coedge->Edge() = nullptr;
        delete m_coedge;
    }

    m_start->Edges().erase(this);
    m_end->Edges().erase(this);

    // 如果孤立，就删除顶点（因为只有 edge 能够获得顶点，只能在这里删除了）
    if (m_start->Edges().empty())
        delete m_start;
    if (m_end->Edges().empty())
        delete m_end;
}

Handle(CAGD::GeomCurve) CAGD::TopoEdge::Geom() const
{
    return m_curve;
}

CAGD::TopoCoedge *&CAGD::TopoEdge::Coedge()
{
    return m_coedge;
}

CAGD::TopoVertex *&CAGD::TopoEdge::Start()
{
    return m_start;
}

CAGD::TopoVertex *&CAGD::TopoEdge::End()
{
    return m_end;
}

CAGD::TopoDir CAGD::TopoEdge::Dir() const
{
    return m_dir;
}

CAGD::TopoType CAGD::TopoEdge::Type() const
{
    return TopoType::EDGE;
}